package dk.lector.domain;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import dk.lector.R;
import dk.lector.datasource.ConfigDBRepository;
import dk.lector.datasource.DocDBRepository;
import dk.lector.datasource.UserDBRepository;
import dk.lector.domain.entities.User;



public class TeamShareMobile extends Application 
{

	private static final String TAG = TeamShareMobile.class.getSimpleName();
	public  User currentUser;
	private boolean configured;
	private long lastUpdate;
	private boolean initialized;

	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "On create is called");
		currentUser = null;
		configured = false;
		initialized = false;
		lastUpdate = System.currentTimeMillis();
		
		registerReceiver(new CoreReciever(), new IntentFilter(getString(R.string.ACTION_SYSTEM_EVENT)));
		systemProcess(R.string.ACTIONCODE_BOOT);	
	
	}
	
	public boolean hasConfig(){return configured;}
	public User getUser(){return currentUser;};
	public boolean isLoggedIn(){return currentUser != null;}
	public boolean isInitialized(){return initialized;};
	public Bundle getState()
	{
		Bundle state = new Bundle();
		state.putParcelable("currentUser", currentUser);
		state.putBoolean("configured", configured);
		state.putBoolean("initialized", initialized);
		state.putLong("lastUpdate", lastUpdate);
		return state;
	}
	
	public void setState(Bundle CompleteStateBundle)
	{
		currentUser = (User) CompleteStateBundle.get("currentUser");
		configured = CompleteStateBundle.getBoolean("configured");
		initialized = CompleteStateBundle.getBoolean("initialized");
		lastUpdate = System.currentTimeMillis();
	}
	
	public void systemProcess(final int actionCode)
	{
		AsyncTask<Void, Void, Void> updateTask = new AsyncTask<Void, Void, Void>() {

			@Override
			protected Void doInBackground(Void... nothing) {
				
				if(actionCode == R.string.ACTIONCODE_BOOT)
				{
				lastUpdate = System.currentTimeMillis();	

				configured = ConfigDBRepository.hasConfig(getBaseContext());
				
				} else {
					configured = ConfigDBRepository.hasConfig(getBaseContext());
					currentUser = UserDBRepository.readUser(getBaseContext());	
					
				}
				
				return null;
			}
			
			@Override
			protected void onPostExecute(Void result) {
				Log.d(TAG, "Post execute recieves actionCode " + getString(actionCode));
				if(actionCode == R.string.ACTIONCODE_BOOT){
				initialized = true;	
				sendBroadcast(new Intent(getBaseContext().getString(R.string.ACTION_STARTUP_COMPLETE)));
				} 
				else if(currentUser!= null)
					updateActivityTimestamp(1, currentUser.getId(), 9000);	
				else
				{
				sendBroadcast(new Intent(getBaseContext().getString(R.string.ACTION_STATE_CHANGED)));	
				}

				super.onPostExecute(result);
			}
		};

		updateTask.execute();	
	}
	public void updateActivityTimestamp(final int UserOrDocument, final int userID, final int documentID)
	{
		//9000 is default value if the intent has no extra.
		if(userID == 9000 && documentID == 9000)return;
		AsyncTask<Void, Void, Void> ActivityTask = new AsyncTask<Void, Void, Void>() {

			@Override
			protected Void doInBackground(Void... nothing) {
				
				long timestamp = System.currentTimeMillis();
				//user
				if(UserOrDocument==1)
				{
					if(currentUser != null)
					UserDBRepository.updateUserActivity(getBaseContext(), timestamp, currentUser.getId());
				}
				//document
				else if(UserOrDocument==2)
				{
					DocDBRepository.updateDocumentAcivity(getBaseContext(), timestamp, documentID);
				}
				return null;
			}
			
			@Override
			protected void onPostExecute(Void result) {

				super.onPostExecute(result);
			}
		};

		ActivityTask.execute();	
		
	}
	@Override
	public boolean stopService(Intent name) {
		return super.stopService(name);
	}

	@Override
	public void sendBroadcast(Intent intent) {
		Log.d(TAG, "Broadcast sent: " + intent.getAction() + " - Expected state is: " + getState());
		super.sendBroadcast(intent);
	}
	
	private class CoreReciever extends BroadcastReceiver
	{
		private final String TAG = CoreReciever.class.getSimpleName();
		
		@Override
		public void onReceive(Context context, Intent intent) {
			int actionCode = intent.getIntExtra("actionCode", 666);
			Log.d(TAG, "System event recieved with action: " + getString(actionCode));
			
			switch (actionCode) {
			case R.string.ACTIONCODE_USER_LOGIN:
				systemProcess(R.string.ACTIONCODE_USER_LOGIN);
				break;
				
			case R.string.ACTIONCODE_USER_LOGOUT:
				currentUser = null;
				lastUpdate = System.currentTimeMillis();
				sendBroadcast(new Intent(getBaseContext().getString(R.string.ACTION_STATE_CHANGED)));
				break;	
			
			case R.string.ACTIONCODE_CONFIG_DOWNLOADED:
				systemProcess(R.string.ACTIONCODE_CONFIG_DOWNLOADED);
				break;
				
			case R.string.ACTIONCODE_CONFIG_DELETED:
				systemProcess(R.string.ACTIONCODE_CONFIG_DELETED);
				break;	

			case R.string.ACTIONCODE_USER_ACTIVITY:
				updateActivityTimestamp(1, intent.getIntExtra("userID", 9000), 9000);
				break;
			case R.string.ACTIONCODE_DOCUMENT_ACTIVITY:
				updateActivityTimestamp(2, 9000 , intent.getIntExtra("documentID", 9000));
				break;
			case R.string.ACTIONCODE_KILL_APPLICATION:
				android.os.Process.killProcess(android.os.Process.myPid());
				break;	
			case R.string.ACTIONCODE_CLEAN_UP_DONE:
				systemProcess(R.string.ACTIONCODE_CLEAN_UP_DONE);
				break;	
				
			default:
				Log.d(TAG, "unknown action!" + actionCode);
				break;
			}
	
		}
	}
}
